#include <openssl/evp.h>
#include <libcitadel.h>
#include "../../config.h"
+#include "../../internet_addressing.h"
// This utility function is used by the body canonicalizer
// hash of the canonicalized body
unsigned char *body_hash = malloc(SHA256_DIGEST_LENGTH);
- SHA256((unsigned char*)relaxed_body, relaxed_body_len, body_hash);
+ SHA256((unsigned char *)relaxed_body, relaxed_body_len, body_hash);
free(relaxed_body); // all we need now is the hash
relaxed_body = NULL;
CtdlSetConfigStr("dkim_selector", new_selector);
}
}
+
+
+// If the DKIM key, DKIM selector, or set of signing domains has changed, we need to tell the administrator about it.
+void dkim_check_advisory(void) {
+
+ // If there is no DKIM ... there is nothing to discuss
+ if (IsEmptyStr(CtdlGetConfigStr("dkim_private_key"))) return;
+ if (IsEmptyStr(CtdlGetConfigStr("dkim_selector"))) return;
+
+ // We're going to build a hash of the private key, the selector, and all signing domains.
+ // The way we build it doesn't matter, and it doesn't even have to be secure.
+ // This is just to let us know that we have to post an update to the administrator if the hash changes.
+
+ StrBuf *hashsrc = NewStrBuf();
+ if (!hashsrc) {
+ return;
+ }
+
+ StrBufAppendBufPlain(hashsrc, CtdlGetConfigStr("dkim_private_key"), strlen(CtdlGetConfigStr("dkim_private_key")), 0);
+ StrBufAppendBufPlain(hashsrc, CtdlGetConfigStr("dkim_selector"), strlen(CtdlGetConfigStr("dkim_selector")), 0);
+
+ char *ptr = inetcfg;
+ while (ptr && *ptr) {
+ char *sep = strchr(ptr, '|');
+ if (sep && !strncasecmp(sep+1, HKEY("localhost"))) {
+ StrBufAppendBufPlain(hashsrc, ptr, sep-ptr, 0);
+ }
+ ptr = strchr(ptr, '\n');
+ if (ptr) ++ptr;
+ }
+
+ // make a hash from the string...
+ unsigned char *config_hash = malloc(SHA256_DIGEST_LENGTH);
+ SHA256((unsigned char *)ChrPtr(hashsrc), StrLength(hashsrc), config_hash);
+ FreeStrBuf(&hashsrc);
+
+ // base64 encode it...
+ char *encoded_config_hash = malloc(SHA256_DIGEST_LENGTH * 2);
+ CtdlEncodeBase64(encoded_config_hash, config_hash, SHA256_DIGEST_LENGTH, BASE64_NO_LINEBREAKS);
+ free(config_hash); // all we need now is the encoded hash
+
+ // Does it match the saved hash?
+ if ( (IsEmptyStr(CtdlGetConfigStr("dkim_config_hash")))
+ || (strcmp(encoded_config_hash, CtdlGetConfigStr("dkim_config_hash")))
+ ) {
+ // No? Post an Aide notification.
+ StrBuf *message = NewStrBuf();
+ StrBufAppendPrintf(message, "%s",
+ " \n"
+ " Your domain configuration may have changed.\n"
+ " To allow the DKIM signatures of outbound mail to be verified, "
+ "please ensure that the following DNS records are created:\n"
+ " \n"
+ );
+
+ ptr = inetcfg;
+ while (ptr && *ptr) {
+ char *sep = strchr(ptr, '|');
+ if (sep && !strncasecmp(sep+1, HKEY("localhost"))) {
+ StrBufAppendPrintf(message, " Record name : %s._domainkey.%s\n",
+ CtdlGetConfigStr("dkim_selector"),
+ "fixme.FIXME.com"
+ );
+ StrBufAppendPrintf(message, " Record type : TXT\n");
+ StrBufAppendPrintf(message, " Record value: c=dkim1 etc. etc. etc.\n");
+ StrBufAppendPrintf(message, " \n");
+ }
+ ptr = strchr(ptr, '\n');
+ if (ptr) ++ptr;
+ }
+
+ CtdlAideMessage(ChrPtr(message), "DKIM records");
+ FreeStrBuf(&message);
+ }
+
+ // Save it to the config database so we don't do this except when it changes.
+ CtdlSetConfigStr("dkim_config_hash", encoded_config_hash);
+ free(encoded_config_hash);
+}